package com.itheima.utils;

import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.Set;
import java.util.concurrent.TimeUnit;

@Component
public class RedisUtil {
    @Resource
    private RedisTemplate<String, Object> redisTemplate;

    //存储键值对（无过期时间）
    public void set(String key, Object value) {
        redisTemplate.opsForValue().set(key, value);
    }

    //存储键值对（带过期时间
    public void set(String key, Object value, long timeout, TimeUnit unit) {
        redisTemplate.opsForValue().set(key, value, timeout, unit);
    }

    //获取值
    public Object get(String key) {
        return redisTemplate.opsForValue().get(key);
    }

    //删除键
    public Boolean delete(String key) {
        return redisTemplate.delete(key);
    }

    //设置过期时间
    public Boolean expire(String key, long tiemout, TimeUnit unit) {
        return redisTemplate.expire(key, tiemout, unit);
    }

    //判断键是否存在
    public Boolean hasKey(String key) {
        return redisTemplate.hasKey(key);
    }

    // ---------------------- 新增 ZSet 类型操作（核心） ----------------------
    /**
     * 向 ZSet 中添加元素（用于存储订单ID和超时时间）
     * @param key ZSet 键名（如 "order:timeout:zset"）
     * @param value 元素值（订单ID）
     * @param score 分数（超时时间戳，用于排序和判断过期）
     * @return 是否添加成功
     */
    public Boolean zAdd(String key,Object value,double score){
        return redisTemplate.opsForZSet().add(key,value,score);
    }

    /**
     * 从 ZSet 中删除元素（用于订单支付成功后移除）
     * @param key ZSet 键名
     * @param values 要删除的元素（订单ID）
     * @return 删除的数量
     */
    public Long zRemove(String key, Object... values) {
        return redisTemplate.opsForZSet().remove(key, values);
    }

    /**
     * 查询 ZSet 中分数在 [min, max] 范围内的元素（用于扫描过期订单）
     * @param key ZSet 键名
     * @param min 最小分数（如 0）
     * @param max 最大分数（如当前时间戳）
     * @return 符合条件的元素集合（订单ID）
     */
    public Set<Object> zRangeByScore(String key, double min, double max) {
        return redisTemplate.opsForZSet().rangeByScore(key, min, max);
    }
}
